#include "eventHandlerTask.h"
#include "spi/configure_device.h"
#include "monitorTimer.h"
#include "dma/dma.h"
#include "gpio/gwGpio.h"
#include "baseband/baseband.h"
#include "ext_uart/ext_uart.h"

static TaskHandle_t xEventHanlerTask;

extern State xState;
/*-----------------------------------------------------------*/
void task1HandleEvent(QueueHandle_t xEventQueue, Event event){
	// xil_printf( "HandleEventTask1 is processing event... %d \r\n", event.ID);

	switch(event.ID){
		case EVENT_MONITOR_TIMEOUT:
		{
			size_t free_size = xPortGetFreeHeapSize();
			xil_printf("free_size = %d ,\r\n",free_size);

			xState.cnt_timer_call = xState.cnt_timer_call + 1;

			if(monitor_204b() != 0){
				if(xState.flag_spi_configuring == 0){
					xState.cnt_spi_configure_failed ++;
					xState.flag_spi_configure_ok = 0;// configure spi again !
					xState.flag_spi_configuring = 1;
					createSpiConfigureTask(xEventQueue);
				}
			}

			agc_check(&xState);

		 	break;
		}
		case EVENT_CONFIGURE_OK:
		{
			xil_printf("EVENT_CONFIGURE_OK : Configure ok and Deleted spiConfigureTask ..... \r\n");

			/* 切换中频模式 */
			gpio_normal();

			xState.flag_spi_configure_ok = 1;
			xState.flag_spi_configuring = 0;
			if(xState.flag_start_timer == 0){ //阻止configure重配置，再初始化组件
				xState.flag_start_timer = 1;
				start_monitor(xEventQueue); // timer task
				
				/* 中断相关在调度器启动后执行，同uart处理 */
				BaseType_t Status;
				Status = init_axidma(xEventQueue);
				configASSERT( Status == XST_SUCCESS );
				int ret = createPrvExtUartRxTask(xEventQueue);
				configASSERT( ret == 0 );
				ret = createBlockExtUartTxTask(xEventQueue);
				configASSERT( ret == 0 );
			}

			break;
		}
		case EVENT_S2MM:
		{
			xil_printf("EVENT_S2MM : Dma Rx completed ..... \r\n");
			xState.dma_state.rx_cnt = xState.dma_state.rx_cnt + 1;
			u32 rx_length = event.src;
			xState.dma_state.rx_length = rx_length;
			int ret = process_rx(rx_length);
			if(ret != 0){
				xState.dma_state.rx_error_cnt ++;
				xState.dma_state.rx_error_ret = ret;
			}

			break;
		}
		case EVENT_DMA_ERROR:
		{
			// BaseType_t Status;
			// Status = init_axidma(xEventQueue);
			// configASSERT( Status == XST_SUCCESS );

			// u32 sender = event.src; // 0: tx -- 1:rx

			break;
		}
		case EVENT_MM2S:
		{
			xil_printf("EVENT_MM2S : Dma tx completed ..... \r\n");

			u32 tx_length = event.src;
			xState.dma_state.tx_length = tx_length;
			// copy_test_tx_data(xState.dma_state.test_TxPacket, tx_length);
			xState.dma_state.tx_cnt = xState.dma_state.tx_cnt + 1;

			u8 rapidIO_tx_idx = tx_length;
			if(xState.dma_state.sendEnFlag == 0 && xState.dma_state.debug_cnt_state.send_en_doorbell_flag == 0){
				rapidIO_tx_idx = rapidIO_tx_idx + 1;
				if(rapidIO_tx_idx == 6){
					rapidIO_tx_idx = 0;
				}
			}

			if(xState.dma_state.debug_cnt_state.send_en_doorbell_flag == 1){
				xState.dma_state.debug_cnt_state.send_en_doorbell_flag = 0;
			}

			// test code
			if(xState.dma_state.tx_test_cnt == 0){
				break;
			}

			if(xState.dma_state.tx_cnt < xState.dma_state.tx_test_cnt){
				gw_sleep(15);
				#ifdef rapidIO_testFlag
				if(dmaTxRapidIOContinue(rapidIO_tx_idx, &(xState.dma_state.sendEnFlag), &(xState.dma_state.sendEnCnt), 
					&(xState.dma_state.tx_120packet_cnt), &xState) != XST_SUCCESS){
					xState.dma_state.tx_error_cnt ++;
				}
				#endif
			}


			break;
		}
		case EVENT_DMA_TEST_ENABLE:
		{
			u8 rapidIO_tx_idx = 0;
			u32 *data_array = (u32*) event.pData;

			xState.dma_state.sendEnFlag = 0;
			xState.dma_state.sendEnCnt = 0;
			xState.dma_state.tx_test_cnt = 0;
			xState.dma_state.tx_120packet_cnt = 0;
			xState.dma_state.tx_cnt = 0;
			xState.dma_state.rx_cnt = 0;
			xState.dma_state.rx_error_cnt = 0;
			xState.dma_state.rx_error_ret = 0;
			xState.dma_state.tx_error_cnt = 0;
			xState.dma_state.debug_cnt_state.rapid_io_1_cnt = 0;
			xState.dma_state.debug_cnt_state.rapid_io_2_cnt = 0;
			xState.dma_state.debug_cnt_state.rapid_io_3_cnt = 0;
			xState.dma_state.debug_cnt_state.rapid_io_4_cnt = 0;
			xState.dma_state.debug_cnt_state.rapid_io_5_cnt = 0;
			xState.dma_state.debug_cnt_state.doorbell_cnt = 0;
			xState.dma_state.debug_cnt_state.send_en_1_cnt = 0;
			xState.dma_state.debug_cnt_state.send_en_2_cnt = 0;
			xState.dma_state.debug_cnt_state.send_en_doorbell_cnt = 0;
			xState.dma_state.debug_cnt_state.send_en_doorbell_flag = 0;

			xState.dma_state.clear_cnt = data_array[1];
			xState.dma_state.tx_test_cnt = data_array[0] * (6 * xState.dma_state.clear_cnt + 3);


			if(xState.dma_state.tx_test_cnt > 0){
				#ifdef rapidIO_testFlag
				if(dmaTxRapidIOContinue(rapidIO_tx_idx, &(xState.dma_state.sendEnFlag), &(xState.dma_state.sendEnCnt), 
					&(xState.dma_state.tx_120packet_cnt), &xState) != XST_SUCCESS){
					xState.dma_state.tx_error_cnt ++;
				}
				#endif
			}

			break;
		}
		case EVENT_EXT_UART_RX_OK:
		{
			xState.ext_uart_state.rx_cnt = xState.ext_uart_state.rx_cnt + 1;
			xState.ext_uart_state.rx_length = event.src;
			memcpy(xState.ext_uart_state.test_extUartRxBuffer, event.pData, xState.ext_uart_state.rx_length);

			break;
		}
		case EVENT_EXT_UART_TX_OK:
		{
			xState.ext_uart_state.tx_cnt = xState.ext_uart_state.tx_cnt + 1;
			xState.ext_uart_state.tx_length = event.src;
			break;
		}
		default:
		{
			break;
		}
	}

	if(event.pData != NULL){
		vPortFree(event.pData); // pvPortMalloc
	}
}

static void eventHandlerTask( void *pvParameters )
{
	QueueHandle_t xEventQueue = (QueueHandle_t)pvParameters;
	Event event;
	for( ;; )
	{
		/* Block to wait for data arriving on the queue. */
		xQueueReceive(xEventQueue, &event, portMAX_DELAY );

		task1HandleEvent(xEventQueue, event);
	}
}

int createEventHandlerTask(QueueHandle_t xEventQueue){
    BaseType_t xReturn = xTaskCreate( eventHandlerTask, 
	                                  (const char *) "eventHandlerTask", 
									  configMINIMAL_STACK_SIZE, 
									  xEventQueue, 
									  tskIDLE_PRIORITY + 1, /* gw_priority */
									  &xEventHanlerTask);
	if(xReturn != pdPASS){
		return -1;
	}
	return 0;
}

/*********************** cli ***************************/
